package eerbaar.v2.pattern.server;

import java.util.ArrayList;
import java.util.List;

import eerbaar.game.IGame;
import eerbaar.memory.IMemory;
import eerbaar.persona.IPersona;
import eerbaar.shared.exceptions.GameException;
import eerbaar.shared.service.ServiceFactory;
import eerbaar.shared.tree.INode;
import eerbaar.shared.tree.IPayload;

public class EventPlayback implements IProgramListener, IEventProducer {

    private INode foundProgram;
    private final List<IEventConsumer> consumers = new ArrayList<IEventConsumer>();

    @Override
    public void addEventConsumer(IEventConsumer sink) {

        if (!this.consumers.contains(sink)) {
            this.consumers.add(sink);
        }
    }

    public void feedEvent(String event) {

        for (IEventConsumer sink : this.consumers) {
            sink.eatEvent(event);
        }
    }

    public INode findProgram(IGame game) {

        IPersona pet = game.getPersona("pet");
        IMemory memory = pet.getHead().getBrain().getMemory();

        IProgramGeneratorFactory factory = ServiceFactory
                .getService(IProgramGeneratorFactory.class);
        IProgramGenerator generator = factory.create();

        generator.addProgramListener(this);

        INode timeNode = memory.getTimeNode();
        INode[] children = timeNode.getChildren();

        for (INode child : children) {

            IPayload payload = child.getPayload();

            final String event = payload.getKey();
            final int count = payload.getMergeCount();

            String eventClass = "cmd";
            String a = child.getAttributes().get(String.class, "class");
            if (a != null) {

                eventClass = a;
            }

            for (int i = 0; i < count + 1; i++) {

                System.out.println("EVENT: " + eventClass + " " + event);
                generator.eatEvent(eventClass, event);
            }
        }

        return this.foundProgram;
    }

    @Override
    public void foundProgram(INode program) {

        this.foundProgram = program;
        System.out.println("foundProgram: " + program.getPayload().getValue());
    }

    @Override
    public void handleException(GameException e) {

    }

    @Override
    public void removeEventConsumer(IEventConsumer consumer) {

        if (this.consumers.contains(consumer)) {
            this.consumers.remove(consumer);
        }
    }

}
